<script setup lang="ts">
import { Edit, User,Delete } from '@element-plus/icons-vue'
import { ref ,onMounted} from 'vue';
import { getUserListAPI,addUserAPI,updateUserAPI,deleteUserAPI,getRoleListByUserAPI, assignRoleAPI,batchDeleteUserAPI } from '@/api/permission/user'
import type { UserItem, UserAddParams ,RoleItem,UserRoleAssignParams} from '@/types/permission/user'
import { ElMessage,ElMessageBox } from 'element-plus'

// 分页参数
const currentPageParams = ref({
    page: 1,
    pageSize: 5,
    total: 0
})

// 切换页码
const changePage = (page: number) => {
    currentPageParams.value.page = page
    getUserList()
}

// 切换每页条数
const changePageSize = (pageSize: number) => {
    currentPageParams.value.pageSize = pageSize
    getUserList()
}

// 用户列表数据
const userListData = ref<UserItem[]>([])

// 获取用户列表
const getUserList = async(username: string = '') => {
    const res = await getUserListAPI(currentPageParams.value.page,currentPageParams.value.pageSize,username)
    console.log(res)
    userListData.value = res.data.records
    currentPageParams.value.total = res.data.total
}

// 添加修改抽屉弹框
const drawerShow = ref(false)

// 新增用户
const addUser = () => {
    drawerShow.value = true
    drawerTitle.value = '添加用户'
}

// 更新用户
const updateUser = (row: UserItem) => {
    drawerShow.value = true
    drawerTitle.value = '更新用户'
    formData.value = {
        id: row.id,
        name: row.name,
        username: row.username,
        password: row.password
    }
}

// 抽屉标题状态
const drawerTitle = ref('添加用户')

// 取消添加修改
const drawerCancel = () => {
    drawerShow.value = false
    formData.value = {
        name: '',
        username: '',
        password: ''
    }
    drawerFormRef.value.resetFields()
}

// 添加用户表单数据
const formData = ref<UserAddParams>({
    name: '',
    username: '',
    password: ''
})

// 添加修改确认、
const drawerConfirm = async() => {
    drawerFormRef.value.validate(async(valid: boolean) => {
        if(valid) {
            if(drawerTitle.value === '添加用户') {
                const res = await addUserAPI(formData.value)
            if(res.code === 200) {
                // 提示用户
                ElMessage.success("添加成功")
            }
            } else {
                // 更新用户
                const res = await updateUserAPI(formData.value)
                if(res.code === 200) {
                    // 提示用户
                    ElMessage.success("更新成功")
                    // 修改用户信息后本地需要重新加载登录用户的信息
                    window.location.reload()
                }
            }
            // 关闭抽屉
            drawerCancel()
            // 更新数据
            getUserList()
        }
    })
    
}

// 抽屉表单校验规则
const rules  ={
    name: [
        { required: true, message: '请输入用户姓名', trigger: 'blur' },
        { min: 2, max: 10, message: '长度在 2 到 10 个字符', trigger: 'blur' }
    ],
    username: [
        { required: true, message: '请输入用户名称', trigger: 'blur' },
    ],
    password: [
        { required: true, message: '请输入用户密码', trigger: 'blur' },
    ]
}

// 抽屉表单对象
const drawerFormRef = ref()

// 批量删除用户数据
const deleteUserListData = ref<UserItem[]>([])

// 表格选择回调
const handleSelectionChange = (selection: UserItem[]) => {
    deleteUserListData.value = selection
}

// 删除用户
const deleteUser = async(id: string | number) => {
    // 发送请求删除用户
    const res = await deleteUserAPI(id)
    if(res.code === 200) {
        // 提示用户
        ElMessage.success("删除成功")
        // 更新界面
        getUserList()
    }
}

// 批量删除用户
const deleteUserList = async() => {
    // 提示用户是否删除
    ElMessageBox.confirm("确定要删除选中的用户吗？","温馨提示",{
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
    }).then(async() => {
        // 处理请求参数
        const idList = deleteUserListData.value.map((item) => item.id) as number[]
        // 发送请求删除用户
        const res = await batchDeleteUserAPI(idList)
        if(res.code === 200) {
            // 提示用户
            ElMessage.success("删除成功")
            // 更新页面
            getUserList()
        }
    }).catch(() => {})
}

// 分配角色弹出对话框
const dialogShow = ref(false)

// 分配角色
const assignRole = async(row: UserItem) => {
    // 保存用户信息
    assignRoleUser.value = row
    // 获取用户角色列表
    await getRoleListByUser(row.id)
    // 开启弹框
    dialogShow.value = true
}

// 分配角色用户信息
const assignRoleUser = ref<UserItem>()

// 属性复选框是否全选
const checkAll= ref(false)

// 全选框样式切换
const isIndeterminate = ref(true)

// 全选
const handleCheckAllChange = (val: boolean) => {
    // 判断是否全选，若全选，则将全部属性赋值给已勾选属性
    assignRoles.value = val ? allRolesList.value : []
    // 改变全选框的状态
    isIndeterminate.value = false
}

// 单选每一个属性项
const handleCheckedCitiesChange = (value: string[]) => {
    // 读取已勾选属性的长度
  const checkedCount = value.length
//   若已勾选属性长度和全部属性长度相等，则全选框便为全选状态
  checkAll.value = checkedCount === allRolesList.value?.length
  // 若已勾选属性长度大于0且小于全部属性长度，则全选框便为半选状态
  isIndeterminate.value = checkedCount > 0 && checkedCount < allRolesList.value!.length
}

// 全部属性
const allRolesList= ref<RoleItem[]>()

// 已勾选属性
const assignRoles = ref<RoleItem[]>()

// 获取用户角色列表
const getRoleListByUser = async(id: string | number) => {
    // 发送请求获取用户角色列表         
    const res = await getRoleListByUserAPI(id)
    // console.log(res);
    // 保存全部属性
    allRolesList.value = res.data.allRolesList
    // 保存已勾选属性
    assignRoles.value = res.data.assignRoles
}

// 关闭弹框
const dialogCancel = () => {
    dialogShow.value = false
}

// 对话框确认
const dialogConfirm = async() => {
    // 处理参数
    const params: UserRoleAssignParams = {
        userId: assignRoleUser.value?.id as number,
        roleIdList: assignRoles.value?.map((item) => item.id) as number[]
    }
    // 发送保存用户角色
    const res = await assignRoleAPI(params)
    if(res.code === 200) {
        // 提示用户
        ElMessage.success("分配角色成功")
        // 关闭弹框
        dialogCancel()
        // 更新界面
        getUserList()
    }
}

// 搜索关键字
const searchKeyword = ref('')


// 搜索
const search = () => {
    getUserList(searchKeyword.value)
}

// 重置
const reset = () => {
    searchKeyword.value = ''
    getUserList()
}

// 初始化
onMounted(() => {
    getUserList()
})
</script>

<template>
    <div class="user">
        <el-card style="height: 80px">
            <el-form inline labe-width="100px" class="searchForm">
                <el-form-item label="用户名:">
                    <el-input v-model="searchKeyword" placeholder="请输入用户名"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button  @click="search" type="primary" :disabled="searchKeyword === ''">搜索</el-button>
                    <el-button type="primary" :disabled="searchKeyword === ''" @click="reset">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card style="margin-top: 20px;">
            <el-row>
                <el-button v-disabled="'btn.User.add'" size="large" type="primary" @click="addUser">添加</el-button>
                <el-button v-disabled="'btn.User.remove'"  size="large" type="primary" @click="deleteUserList">批量删除</el-button>
            </el-row>
            <el-table @selection-change="handleSelectionChange" stripe border :data="userListData" style="margin-top: 20px;">
                <el-table-column align="center" type="selection" width="60px"></el-table-column>
                <el-table-column  align="center" type="index" label="序号" width="60px"></el-table-column>
                <el-table-column prop="id" align="center" label="id" width="60px"></el-table-column>
                <el-table-column prop="name" align="center" show-overflow-tooltip label="用户姓名" ></el-table-column>
                <el-table-column prop="username" align="center" show-overflow-tooltip label="用户名称" ></el-table-column>
                <el-table-column prop="roleName" align="center" show-overflow-tooltip label="用户角色" ></el-table-column>
                <el-table-column prop="createTime" show-overflow-tooltip align="center" label="创建时间" ></el-table-column>
                <el-table-column prop="updateTime" show-overflow-tooltip align="center" label="更新时间" ></el-table-column>
                <el-table-column width="360px" align="center" label="操作" >
                    <template v-slot="{ row }">
                        <el-button v-disabled="'btn.User.assgin'" :data="row" type="primary" :icon="User" size="small" @click="assignRole (row)">分配角色</el-button>
                        <el-button v-disabled="'btn.User.update'" @click="updateUser(row)" type="primary" :icon="Edit" size="small">编辑</el-button>
                        <el-popconfirm title="确定要删除该用户吗?" confirm-button-text="确定" cancel-button-text="取消" @confirm="deleteUser(row.id)">
                            <template #reference>
                                <el-button v-disabled="'btn.User.remove'" type="primary" :icon="Delete" size="small">删除</el-button>
                            </template>
                        </el-popconfirm>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination
            style="margin: 10px 0;"
            v-model:current-page="currentPageParams.page"
            v-model:page-size="currentPageParams.pageSize"
            :background="true"
            :page-sizes="[3,5, 10, 20]"
            layout=" prev, pager, next, jumper,-> ,total, sizes"
            :total="currentPageParams.total"
            @size-change="changePageSize"
            @current-change="changePage"
            />
        </el-card>
        <!-- 抽屉组件 -->
        <el-drawer @close="drawerCancel"  v-model="drawerShow">
            <template #header>
                <span>{{drawerTitle }}</span>
            </template>
            <template #default >
                <el-form ref="drawerFormRef" :rules="rules" :model="formData" label-width="100px">
                    <el-form-item label="用户名" prop="username">
                        <el-input v-model="formData.username" placeholder="请输入用户名"></el-input>
                    </el-form-item>
                    <el-form-item label="用户昵称" prop="name"> 
                        <el-input v-model="formData.name" placeholder="请输入用户昵称"></el-input>
                    </el-form-item>
                    <el-form-item v-if="drawerTitle === '添加用户'" label="用户密码" prop="password">
                        <el-input v-model="formData.password" placeholder="请输入用户密码"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button @click="drawerCancel " type="primary">取消</el-button>
                        <el-button @click="drawerConfirm"  type="primary">确定</el-button>
                    </el-form-item>
                </el-form>
            </template>
        </el-drawer>

        <!-- 对话框组件 -->
        <el-dialog
            v-model="dialogShow"
            title="分配角色"
            width="500"
            @close="dialogCancel"
        >
            <el-form la1bel-width="100px">
                <el-form-item label="用户姓名">
                    <el-input disabled v-model="assignRoleUser!.name"></el-input>
                </el-form-item>
                <el-form-item label="用户角色">
                    <el-checkbox
                        v-model="checkAll"
                        :indeterminate="isIndeterminate"
                        @change="handleCheckAllChange"
                        >全选</el-checkbox
                    >
                    <el-checkbox-group v-model="assignRoles" @change="handleCheckedCitiesChange">
                        <el-checkbox
                        v-for="item in allRolesList"
                        :key="item.id"
                        :label="item"
                        >{{ item.roleName }}</el-checkbox
                        >
                    </el-checkbox-group>
                </el-form-item>
            </el-form>
            <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="dialogCancel">取消</el-button>
                <el-button type="primary" @click="dialogConfirm">
                确认
                </el-button>
            </div>
            </template>
        </el-dialog>
         <!-- 对话框组件 -->
    </div>
</template>


<style scoped lang="scss">
.searchForm {
    display: flex;
    justify-content: space-between;
    padding: 0 20px;
}
</style>